package com.nuc.zyt.day05.nio.demo;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;

/**
 * @ClassName Server nio群聊系统
 * @Description TODO
 * @Author 耀酱
 * @Date 2023/5/31 12:14
 * @Version 1.0
 */

public class Server {

    private Selector selector; // 选择器
    private ServerSocketChannel ssC;
    private static final int PORT = 9999;


    public Server(){
        try{
            selector = Selector.open();

            ssC = ServerSocketChannel.open();

            ssC.bind(new InetSocketAddress(PORT));

            ssC.configureBlocking(false);  // 设置非阻塞

            ssC.register(selector, SelectionKey.OP_ACCEPT); //注册端口

        }catch (Exception e){

        }


    }

    public static void main(String[] args) {

        Server server = new Server();

        server.listen();


    }

    private void listen() {
        // 监听
        try {
            while (selector.select() > 0){
                Iterator<SelectionKey> it = selector.selectedKeys().iterator();
                while (it.hasNext()){
                    SelectionKey sk = it.next();
                    if(sk.isAcceptable()){
                        // 客户端接入请求
                        // 获取通道
                        SocketChannel socketChannel = ssC.accept();
                        ssC.configureBlocking(false);

                        ssC.register(selector,SelectionKey.OP_READ);
                    }else if(sk.isReadable()){
                        // 处理当前客户端消息，
                        readClientData(sk);


                    }
                    it.remove(); // 处理完毕移除事件
                }


            }
        }catch (Exception e){

        }

    }

    private void readClientData(SelectionKey sk) throws IOException {
        SocketChannel socketChannel = null;
        try{
            socketChannel  = (SocketChannel) sk.channel();

            ByteBuffer buffer = ByteBuffer.allocate(1024);

            int count = socketChannel.read(buffer);
            if(count>0){
                // 提取信息
                buffer.flip();
                String msg = new String(buffer.array(),0,buffer.remaining());
                System.out.println(msg);

                sendMsgToAllClient(msg,socketChannel);

            }

        }catch (Exception e){
            System.out.println();
            sk.cancel(); //取消注册
            ssC.close();

        }

    }

    /**
     *
     * @param mag
     * @param socketChannel
     */
    private void sendMsgToAllClient(String mag, SocketChannel socketChannel) throws IOException {
        System.out.println("服务端转发，当前线程："+Thread.currentThread().getName());
        for(SelectionKey key: selector.keys()){
          Channel channel = key.channel();
            if(channel instanceof SocketChannel && channel != socketChannel){
                ByteBuffer buffer = ByteBuffer.wrap(mag.getBytes());
                ((SocketChannel)channel).write(buffer);
            }
        }

    }


}
